﻿using System;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System8Equations;
using Microsoft.Silverlight.Testing;
using Numbers;

namespace t_System8Equations
{
    [TestClass]
    public class t_System8UpdatingResults
    {
        System8UpdatingResults results;
        static Value n, p, n1, n2, p1, p2, n12, p12;

        [TestInitialize]
        public void TestSetup()
        {
            n = new Value();
            p = new Value();
            n1 = new Value();
            n2 = new Value();
            p1 = new Value();
            p2 = new Value();
            n12 = new Value();
            p12 = new Value();
            results = new System8UpdatingResults(n, p, n1, n2, p1, p2, n12, p12);
        }

        [TestMethod]
        public void TestCtor()
        {
        }

        [TestMethod]
        public void TestInitialResults()
        {
            Assert.AreEqual(-100000000, results.effLT, "Expected effLT to be zero");
            Assert.AreEqual(-100000000, results.effSLT, "Expected effSLT to be zero!");
            Assert.AreEqual(-100000000, results.fakeLT, "Expected initial LT fake rate to be zero!");
            Assert.AreEqual(-100000000, results.fakeSLT, "Expected initial SLT fake rate to be zero!");
        }

        [TestMethod]
        public void TestACalc()
        {
            n.Val = 497008;
            p.Val = 26790;
            n1.Val = 60463;
            n2.Val = 213012;
            p1.Val = 7159;
            p2.Val = 16886;
            n12.Val = 36807;
            p12.Val = 5130;

            Assert.IsTrue(CloseTo(results.fakeLT, 0.050516373700456967), "epmistag1 isn't quite right!?");
            Assert.IsTrue(CloseTo(results.fakeSLT, 0.33001271512623803), "epmistag1 isn't quite right!?");
            Assert.IsTrue(CloseTo(results.effLT, 0.34399663789016915), "epmistag1 isn't quite right!?");
            Assert.IsTrue(CloseTo(results.effSLT, 0.73669071849976586), "epmistag1 isn't quite right!?");
        }

        [TestMethod]
        public void TestChanged()
        {
            List<string> propNames = new List<string>();
            results.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler((o, args) =>
            {
                propNames.Add(args.PropertyName);
            });

            for (int i = 0; i < 8; i++)
            {
                ResetAll();
                SetAllButOne(i);
                propNames.Clear();
                SetLastOne(i);
                Assert.AreEqual(4, propNames.Count, "When setting " + i + " last, didn't see an update!");
            }
        }

        /// <summary>
        /// Return to some zero state
        /// </summary>
        private void ResetAll()
        {
            n.Val = 0;
            p.Val = 0;
            n1.Val = 0;
            n2.Val = 0;
            p1.Val = 0;
            p2.Val = 0;
            n12.Val = 0;
            p12.Val = 0;
        }

        [TestMethod]
        public void TestInitialCalc()
        {
            System8UpdatingResults results;
            Value n, p, n1, n2, p1, p2, n12, p12;

            n = new Value();
            p = new Value();
            n1 = new Value();
            n2 = new Value();
            p1 = new Value();
            p2 = new Value();
            n12 = new Value();
            p12 = new Value();
            n.Val = 497008;
            p.Val = 26790;
            n1.Val = 60463;
            n2.Val = 213012;
            p1.Val = 7159;
            p2.Val = 16886;
            n12.Val = 36807;
            p12.Val = 5130;
            results = new System8UpdatingResults(n, p, n1, n2, p1, p2, n12, p12);

            Assert.IsTrue(CloseTo(results.fakeLT, 0.050516373700456967), "epmistag1 isn't quite right!?");
            Assert.IsTrue(CloseTo(results.fakeSLT, 0.33001271512623803), "epmistag1 isn't quite right!?");
            Assert.IsTrue(CloseTo(results.effLT, 0.34399663789016915), "epmistag1 isn't quite right!?");
            Assert.IsTrue(CloseTo(results.effSLT, 0.73669071849976586), "epmistag1 isn't quite right!?");
        }

        List<Action<int>> setVars = new List<Action<int>>() {
            i => n.Val = 497008,
            i =>    p.Val = 26790,
            i =>    n1.Val = 60463,
                i => n2.Val = 213012,
              i =>  p1.Val = 7159,
              i =>  p2.Val = 16886,
              i =>  n12.Val = 36807,
              i =>  p12.Val = 5130,
        };

        private void SetLastOne(int theOne)
        {
            setVars[theOne](10);
        }

        private void SetAllButOne(int theOne)
        {
            for (int i = 0; i < 8; i++)
            {
                if (i != theOne)
                {
                    setVars[i](10);
                }
            }
        }
        private bool CloseTo(double found, double expected)
        {
            double delta = System.Math.Abs(found - expected);
            return (delta / expected) < 0.05;
        }
    }
}